/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.udt.designtime.api.json;


import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.CommonDtmCollection;
import com.inspur.edp.cef.designtime.api.collection.CommonValCollection;
import com.inspur.edp.cef.designtime.api.collection.GspFieldCollection;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.json.SerializerUtils;
import com.inspur.edp.cef.designtime.api.json.operation.CommonDtmDeserializer;
import com.inspur.edp.cef.designtime.api.json.operation.CommonValDeserializer;
import com.inspur.edp.cef.designtime.api.operation.CommonDetermination;
import com.inspur.edp.cef.designtime.api.operation.CommonValidation;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.TransmitType;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.UdtDbInfo;
import com.inspur.edp.udt.designtime.api.entity.element.ElementCollection;

;

public class ComplexDataTypeDeserializer extends UdtDeserializer {

	@Override
	protected void beforeUdtDeserializer(UnifiedDataTypeDef value) {
		ComplexDataTypeDef dataType = (ComplexDataTypeDef) value;
		dataType.setDbInfo(new UdtDbInfo());
		dataType.setElements(new ElementCollection());
		dataType.setDtmBeforeSave(new CommonDtmCollection());
		dataType.setDtmAfterCreate(new CommonDtmCollection());
		dataType.setDtmAfterModify(new CommonDtmCollection());
	}


	@Override
	protected UnifiedDataTypeDef createUnifiedDataType() {
		return new ComplexDataTypeDef();
	}


	@Override
	protected void readBasicInfo(JsonParser jsonParser, UnifiedDataTypeDef value, String propertyName) {

		if (!(value instanceof ComplexDataTypeDef)) {
			throw new RuntimeException("错误的类型");
		}
		ComplexDataTypeDef dataType = (ComplexDataTypeDef) value;

		switch (propertyName) {
			case UdtNames.DbInfo:
				readDbInfo(jsonParser, dataType);
				break;
			case UdtNames.Elements:
				readElements(jsonParser, dataType);
				break;
			case UdtNames.DtmBeforeSave:
				readDtmBeforeSave(jsonParser, dataType);
				break;
			case UdtNames.DtmAfterModify:
				readDtmAfterModify(jsonParser, dataType);
				break;
			case UdtNames.DtmAfterCreate:
				readDtmAfterCreate(jsonParser, dataType);
				break;
			case UdtNames.TransmitType:
				dataType.setTransmitType(
						SerializerUtils.readPropertyValue_Enum(jsonParser, TransmitType.class, TransmitType.values()));
				break;
//			case UdtNames.ValAfterModify:
//				readValAfterModify(jsonParser, dataType);
//				break;
//			case UdtNames.ValBeforeSave:
//				readValBeforeSave(jsonParser, dataType);
//				break;
			default:
				throw new RuntimeException("未定义的属性名" + propertyName);


		}
	}

	private CommonValCollection readCommonValidationCollection(JsonParser jsonParser) {
		CommonValCollection collection = new CommonValCollection();
		CommonValDeserializer der = new CommonValDeserializer();
		SerializerUtils.readArray(jsonParser, der, collection);
		return collection;
	}

	private CommonDtmCollection readCommonDtmCollection(JsonParser jsonParser) {
		CommonDtmCollection collection = new CommonDtmCollection();
		CommonDtmDeserializer der = new CommonDtmDeserializer();
		SerializerUtils.readArray(jsonParser, der, collection);
		return collection;
	}

	private void readDbInfo(JsonParser jsonParser, ComplexDataTypeDef dataType) {
		SerializerUtils.readStartObject(jsonParser);
		dataType.setDbInfo(new UdtDbInfo());
		SerializerUtils.readPropertyName(jsonParser);
		dataType.getDbInfo().setMappingType(SerializerUtils.readPropertyValue_Enum(jsonParser, ColumnMapType.class, ColumnMapType.values()));
		SerializerUtils.readEndObject(jsonParser);
	}

	private void readElements(JsonParser jsonParser, ComplexDataTypeDef dataType) {
		ElementCollection collection = new ElementCollection();
		UdtElementDeserializer der = new UdtElementDeserializer();
		SerializerUtils.readArray(jsonParser, der, collection);
		handleContainElements(collection, dataType);
		dataType.setElements(collection);
	}

	private void handleContainElements(GspFieldCollection collection, ComplexDataTypeDef commonDataType) {
		for (IGspCommonField field : collection) {
			field.setBelongObject(commonDataType);
			if (field.getChildAssociations() != null && field.getChildAssociations().getCount() > 0) {
				for (GspAssociation association : field.getChildAssociations()) {
					if (association.getRefElementCollection() != null) {
						for (IGspCommonField assofield : association.getRefElementCollection()) {
							assofield.setBelongObject(commonDataType);
						}
					}
				}
			}
		}
	}

	/**
	 ValAfterModify的反序列化

	 @param jsonParser
	 @param dataType
	 */
//	protected final void readValAfterModify(JsonParser jsonParser, ComplexDataTypeDef dataType)
//	{
//		//dataType.setValBeforeSave(this.readCommonValidationCollection(jsonParser));
//	}

	/**
	 ValBeforeSave的反序列化

	 @param jsonParser
	 @param dataType
	 */
//	protected final void readValBeforeSave(JsonParser jsonParser, ComplexDataTypeDef dataType)
//	{
//		//dataType.setValBeforeSave(this.readCommonValidationCollection(jsonParser));
//
//	}

	/**
	 * DtmAfterModify反序列化
	 *
	 * @param jsonParser
	 * @param dataType
	 */
	protected final void readDtmAfterModify(JsonParser jsonParser, ComplexDataTypeDef dataType) {
		dataType.setDtmAfterModify(this.readCommonDtmCollection(jsonParser));
	}

	/**
	 * DtmBeforeSave反序列化
	 *
	 * @param jsonParser
	 * @param dataType
	 */
	protected final void readDtmBeforeSave(JsonParser jsonParser, ComplexDataTypeDef dataType) {
		dataType.setDtmBeforeSave(this.readCommonDtmCollection(jsonParser));
	}

	/**
	 * DtmAfterCreate的反序列化
	 *
	 * @param jsonParser
	 * @param dataType
	 */
	protected final void readDtmAfterCreate(JsonParser jsonParser, ComplexDataTypeDef dataType) {
		dataType.setDtmAfterCreate(this.readCommonDtmCollection(jsonParser));
	}

	/**
	 * Validation的反序列化
	 *
	 * @param jsonParser
	 * @return
	 */
	protected final CommonValidation readValidation(JsonParser jsonParser) {
		CommonValidation info = new CommonValidation();
		while (jsonParser.getCurrentToken() == JsonToken.FIELD_NAME) {
			readValidation(jsonParser, info);
		}
		return info;
	}

	protected final void readValidation(JsonParser jsonParser, CommonValidation info) {
		String propertyName = SerializerUtils.readPropertyName(jsonParser);
		switch (propertyName) {
			case UdtNames.ID:
				info.setID(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.Code:
				info.setCode(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.Name:
				info.setName(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.Description:
				info.setDescription(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.ComponentId:
				info.setComponentId(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.ComponentPkgName:
				info.setComponentPkgName(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.ComponentName:
				info.setComponentName(SerializerUtils.readPropertyValue_String(jsonParser));
				break;

		}


	}

	/**
	 * Determination的反序列化
	 *
	 * @param jsonParser
	 * @return
	 */
	protected final CommonDetermination readDetermination(JsonParser jsonParser) {
		CommonDetermination info = new CommonDetermination();
		while (jsonParser.getCurrentToken() == JsonToken.FIELD_NAME) {
			readDetermination(jsonParser, info);
		}
		return info;
	}

	protected final void readRequestElements(JsonParser jsonParser, CommonDetermination dtm) {
		if (SerializerUtils.readNullObject(jsonParser)) {
			return;
		}
		SerializerUtils.readStartArray(jsonParser);
		while (jsonParser.getCurrentToken() == JsonToken.VALUE_STRING) {
			String item = SerializerUtils.readPropertyValue_String(jsonParser);
			dtm.getRequestElements().add(item);
		}
		SerializerUtils.readEndArray(jsonParser);
	}

	protected final void readDetermination(JsonParser jsonParser, CommonDetermination info) {
		String propertyName = SerializerUtils.readPropertyName(jsonParser);
		switch (propertyName) {
			case UdtNames.ID:
				info.setID(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.Code:
				info.setCode(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.Name:
				info.setName(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.Description:
				info.setDescription(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.ComponentId:
				info.setComponentId(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case UdtNames.ComponentPkgName:
				info.setComponentPkgName(SerializerUtils.readPropertyValue_String(jsonParser));
			case UdtNames.ComponentName:
				info.setComponentName(SerializerUtils.readPropertyValue_String(jsonParser));
			case UdtNames.RequestElements:
				readRequestElements(jsonParser, info);
				break;
		}

	}
}
